package tech.horgee.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tech.horgee.entity.Attendance;
import tech.horgee.entity.Dict;
import tech.horgee.entity.User;
import tech.horgee.enums.AttendStatusEnum;
import tech.horgee.enums.AttendTypeEnum;
import tech.horgee.mapper.AttendanceMapper;
import tech.horgee.mapper.DictMapper;
import tech.horgee.mapper.UserMapper;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 迟到任务
 */
@Component
@RequiredArgsConstructor
public class LateTask {
    private final AttendanceMapper attendanceMapper;
    private final DictMapper dictMapper;
    private final UserMapper userMapper;

    /**
     * 每日凌晨 3 点执行
     */
    @Scheduled(cron = "0 0 3 * * ?")
//    @Scheduled(cron = "0 0/1 * * * ?")
    public void run() {
        Dict dict = dictMapper.selectOne(new LambdaQueryWrapper<Dict>().eq(Dict::getId, 2));
        String dictValue = dict.getValue();
        String[] times = dictValue.split(";");
        LocalTime startTime = LocalTime.parse(times[0]);
        LocalTime endTime = LocalTime.parse(times[1]);

        LocalDate yesterday = LocalDate.now().minusDays(1);
        List<Attendance> list = attendanceMapper.selectList(
                new LambdaQueryWrapper<Attendance>().eq(Attendance::getSignDate, yesterday)
        );
        list.forEach(row -> {
            if (row.getSignTime().isAfter(startTime) || row.getExitTime().isBefore(endTime)) {
                row.setStatus(AttendStatusEnum.PENDING);
                attendanceMapper.updateById(row);
            }
        });
        // 插入未考勤人员的记录
        Set<Long> existUserIds = list.stream().map(Attendance::getUserId).collect(Collectors.toSet());
        List<Attendance> attendances = userMapper.selectList(new LambdaQueryWrapper<User>().select(User::getUserId))
                .stream().map(User::getUserId)
                .filter(userId -> !existUserIds.contains(userId))
                .map(userId -> {
                    Attendance attendance = new Attendance();
                    attendance.setUserId(userId);
                    attendance.setSignDate(yesterday);
                    attendance.setStatus(AttendStatusEnum.PENDING);
                    attendance.setType(AttendTypeEnum.NONE);
                    return attendance;
                }).collect(Collectors.toList());
        attendanceMapper.insertBatchSomeColumn(attendances);
    }
}
